﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Scheduler;

namespace PhoneApp1
{
    public partial class SequencePuzzle : PhoneApplicationPage
    {

        /**
        * This array contains the image names for the sequence puzzle
        * */
        static string[] seqImgNames = new string[] 
        { 
            "blacktriangle.png",    // 0
            "BlackXBrownBG.png",    // 1
            "bluetriangle.png",     // 2
            "BlueXRedBG.png",       // 3
            "BrownCircle.png",      // 4
            "greycircle.png",       // 5
            "marooncircle.png",     // 6
            "orangetriangle.png",   // 7
            "RedXPinkBG.png"        // 8
        };

        // Keeps track of the remaining seconds in the countdown
        int countdown = 10;

        // Keep track of the number of seq imgs that the user has found
        // so we know when to deactive the alarm.
        int numberOfSeqImgsFound = 0;

        // Keep track of the number of errors they've made when searching for the image
        int numberOfUserErrors = 0;

        // Create an array which contains values of 0 or 1.
        // This array represents if an image ID has been chosen or not.
        static Boolean[] hasSeqImgIDBeenChosen = new Boolean[seqImgNames.Length];
        
        // This array stores the string for the file name of the chosen
        // sequence images which are going to display initially. It's needed 
        // for tracking later on. 
        static String[] chosenSeqImageFileName = new String[3];

        // Store the thread for the countdown
        System.Windows.Threading.DispatcherTimer dt = null;

        public static void populateArray()
        {
            for (int i = 0; i < hasSeqImgIDBeenChosen.Length; i++)
            {
                hasSeqImgIDBeenChosen       [i]     = false;
            }
        }

        /**
         * This method returns a random image ID. If the image
         * It ensures that an image cannot be chosen more than once.*/
        public int getRandomImageID()
        {
            Random random = new Random();

            int randID = random.Next(seqImgNames.Length);

            while (hasSeqImgIDBeenChosen[randID] == true)
            {
                randID = random.Next(seqImgNames.Length);
            }

            hasSeqImgIDBeenChosen[randID] = true;
            return randID;
        }


        public SequencePuzzle()
        {
            InitializeComponent();
            initSequencePuzzle();
        }

        void dt_Tick(object sender, EventArgs e)
        {
            countdown--;
            string countText = "" + countdown + "s";
            countdownText.Text = countText;

            if (countdown <= 0)
            {
                dt.Stop();
                dt = null;
                this.showNewImages();
                return;
            }
        }

        /**
         * Initialises the sequence puzzle
         * */
        private void initSequencePuzzle()
        {
            // Reset all of the data when the sequence puzzle initialises
            // incase this isn't a new initialisation but instead the user is starting again
            countdown = 10;
            numberOfSeqImgsFound = 0;
            numberOfUserErrors = 0;

            populateArray();

            countdownText.Text = "10s";

            memoriseText.Visibility = Visibility.Visible;
            countdownText.Visibility = Visibility.Visible;
            solveInstructions.Visibility = Visibility.Collapsed;

            seq4.Visibility = Visibility.Collapsed;
            seq5.Visibility = Visibility.Collapsed;
            seq6.Visibility = Visibility.Collapsed;
            seq7.Visibility = Visibility.Collapsed;
            seq8.Visibility = Visibility.Collapsed;
            seq9.Visibility = Visibility.Collapsed;

            String filename;

            // Image 1
            filename = "/Images/sequence/" + seqImgNames[getRandomImageID()];
            chosenSeqImageFileName[0] = filename;
            BitmapImage image = new BitmapImage(new Uri(filename, UriKind.Relative));
            seq1.Source = image;
            seq1.Visibility = Visibility.Visible;

            // Image 2
            filename = "/Images/sequence/" + seqImgNames[getRandomImageID()];
            chosenSeqImageFileName[1] = filename;
            image = new BitmapImage(new Uri(filename, UriKind.Relative));
            seq2.Source = image;
            seq2.Visibility = Visibility.Visible;

            // Image 3
            filename = "/Images/sequence/" + seqImgNames[getRandomImageID()];
            chosenSeqImageFileName[2] = filename;
            image = new BitmapImage(new Uri(filename, UriKind.Relative));
            seq3.Source = image;
            seq3.Visibility = Visibility.Visible;

            /**
             * Start a thread for the countdown **/
            if (dt != null)
            {
                dt.Stop();
            }

            dt = new System.Windows.Threading.DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, 0, 1000); // 1 second
            dt.Tick += new EventHandler(dt_Tick);
            dt.Start();
        }
  
        /**
         * Upon the countdown finishing, this method 
         * shows all of the new images that the user must select to solve the puzzle.
         * */
        private void showNewImages()
        {
            // Hide the instruction text and the countdown text
            memoriseText.Visibility = Visibility.Collapsed;
            countdownText.Visibility = Visibility.Collapsed;

            // Show the new instructions
            solveInstructions.Visibility = Visibility.Visible; 

            // Randomize the images in the array
            string[] shuffle = RandomStringArrayTool.RandomizeStrings(seqImgNames);

            BitmapImage image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[0], UriKind.Relative));
            seq1.Source = image;
            seq1.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[1], UriKind.Relative));
            seq2.Source = image;
            seq2.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[2], UriKind.Relative));
            seq3.Source = image;
            seq3.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[3], UriKind.Relative));
            seq4.Source = image;
            seq4.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[4], UriKind.Relative));
            seq5.Source = image;
            seq5.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[5], UriKind.Relative));
            seq6.Source = image;
            seq6.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[6], UriKind.Relative));
            seq7.Source = image;
            seq7.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[7], UriKind.Relative));
            seq8.Source = image;
            seq8.Visibility = Visibility.Visible;

            image = new BitmapImage(new Uri("/Images/sequence/" + shuffle[8], UriKind.Relative));
            seq9.Source = image;
            seq9.Visibility = Visibility.Visible;
        }

        /**
         * Return's true if the Image parameter was previously in the sequence puzzle
         * otherwise false
         **/
        private Boolean isImageInSequence(Image seqImg)
        {
            for (int i = 0; i < 3; i++)
            {
                if (((BitmapImage)seqImg.Source).UriSource.ToString().Equals(chosenSeqImageFileName[i]))
                {
                    return true;
                }
            }
            return false;
        }

        /**
         * Called when the user presses the seq1 button
         * */
        private void seq1Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            // If the countdown is not finished then don't do any of the checking for puzzle solves
            if (countdown != 0)
            {
                return;
            }

            seq1.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq1))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq2Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            // If the countdown is not finished then don't do any of the checking for puzzle solves
            if (countdown != 0)
            {
                return;
            }
            
            seq2.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq2))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq3Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            // If the countdown is not finished then don't do any of the checking for puzzle solves
            if (countdown != 0)
            {
                return;
            }
            
            seq3.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq3))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq4Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            seq4.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq4))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq5Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            seq5.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq5))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq6Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            seq6.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq6))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq7Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            seq7.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq7))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                    return;
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq8Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            seq8.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq8))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                    return;
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        private void seq9Tapped(object sender, System.Windows.Input.GestureEventArgs e)
        {
            seq9.Visibility = Visibility.Collapsed;
            if (isImageInSequence(seq9))
            {
                numberOfSeqImgsFound++;
                MessageBox.Show("Correct! Found " + numberOfSeqImgsFound + "/3 sequence images.");
                if (numberOfSeqImgsFound == 3)
                {
                    deactivateAlarm();
                    return;
                }
            }
            else
            {
                UserTapWrongImage();
                return;
            }
        }

        /**
         * This event is called when a user presses the wrong image and handles
         * the starting of a new game. */
        private void UserTapWrongImage()
        {
            MessageBox.Show("Incorrect! " + ++numberOfUserErrors + "/2 mistakes made.");
            if (numberOfUserErrors >= 2)
            {
                MessageBox.Show("Starting new game...");
                initSequencePuzzle();
            }
        }

        private void deactivateAlarm()
        {
            // Disable all alarms if the puzzle is solved!
            for (int i = 0; i < 50; i++)
            {
                ScheduledAction a1 = ScheduledActionService.Find("student_alarm_clock_" + i);
                if (a1 != null)
                {
                    ScheduledActionService.Remove("student_alarm_clock_" + i);
                }
            }
            MessageBox.Show("Alarm deactivated.");
            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.RelativeOrAbsolute));
        }
    }
}